using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using NUnit.Framework;

namespace Universe.Threading.Test
{
    [TestFixture]
    public class TestLock_Advanced
    {
        private readonly int WordingSetSize = 1000;

        public TestLock_Advanced()
        {
            Run(2, 2);
        }

        [SetUp]
        public void Setup()
        {
        }

        [Test]
        public void Test_OnlyWriters()
        {
            Run(1, WordingSetSize);
        }

        [Test]
        public void Test_OneWriterPer10Readers()
        {
            Run(11, WordingSetSize);
        }

        [Test]
        public void Test_OnlyReaders()
        {
            Run(int.MaxValue, WordingSetSize);
        }


        static void Run(int writersPerIteration, int count)
        {
            Lock Sync = new Lock();
            
            Parallel.ForEach(RangeFor<Int32>.Forward(1,count), 10, 3,
                delegate(int index, int element)
                    {
                        using(Sync.Reader)
                        {
                            if (index % writersPerIteration == 0)
                            {
                                using (Sync.Writer)
                                {
                                    FakeJob();
                                }
                            }
                            else
                            {
                                using (Sync.Reader)
                                {
                                    FakeJob();
                                }
                            }
                        }
                    });
        }

        static void FakeJob()
        {
            Thread.Sleep(TimeSpan.FromMilliseconds(1));
        }
    }
}
